為了測試,我們把預設的專案改成使用 redux 的形式吧~
安裝 redux toolkit
npm install @reduxjs/toolkit react-redux
在src 底下新增名稱為 app 的資料夾 , 再新增一個 store.ts
// app/store.ts
import { configureStore } from "@reduxjs/toolkit";
import counterSlice from "./counterSlice";
const store = configureStore({
reducer: {
counter: counterSlice,
},
});
export default store;
新增counterSlice.ts
// store/counterSlice.ts
import { createSlice } from "@reduxjs/toolkit";
export const initialState = {
value: 0,
};
export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
reset : (state) => {
state.value = 0;
}
},
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
main.tsx 加入 Provider
// src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { Provider } from 'react-redux'
import store from './app/store.ts'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
)
改寫 App.tsx
// App.tsx
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './app/counterSlice'import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { Provider } from 'react-redux'
import store from './app/store.ts'
function App() {
const counter = useSelector((state: any) => state.counter.value)
const dispatch = useDispatch()
return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
count is {counter}
<div className="card">
<div>
<button className="button" onClick={() => dispatch(increment())}>
increment
</button>
<button className="button" onClick={() => dispatch(decrement())}>
decrement
</button>
</div>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default App
那我們這個測試跟 useState
的測試其實很像,檢查狀態的更新使否正確,在測試Redux時,我們可以使用 store.getState()
、store.dispatch
來查看 store 狀態跟調用 action ,當然有使用async/await
也可以測試,結合 Day 10 的觀念就可以囉~
// counterSlice.test.ts
import store from ".";
describe("counterSlice", () => {
it("should increment", () => {
store.dispatch({ type: "counter/increment" });
expect(store.getState().counter.value).toEqual(1);
});
it("should decrement", () => {
store.dispatch({ type: "counter/decrement" });
expect(store.getState().counter.value).toEqual(0);
});
it("should reset", () => {
store.dispatch({ type: "counter/reset" });
expect(store.getState().counter.value).toEqual(0);
});
});
為了站著把錢掙了
我來公司只辦三件事,測試!測試!還是他媽的測試!
祝大家測試愉快~